home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Precision Software Appli…tions Silver Collection 1
/
Precision Software Applications Silver Collection Volume One (PSM) (1993).iso
/
demos
/
devel3.exe
/
SEGIO.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-05
|
9KB
|
322 lines
/* Segment file i/o */
/* Written by Bernie Roehl, March 1992 */
/* Copyright 1992 by Bernie Roehl.
May be freely used to write software for release into the public domain;
all commercial endeavours MUST contact Bernie Roehl
for permission to incorporate any part of this software into their
products!
*/
/* The format of a segment file is simple, and very C-like. Each segment
is bounded by { and }, and contains any combination of attributes and
additional segments (which are children of the segment they appear in).
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "rend386.h"
#include "plg.h"
#include "segio.h"
int readseg_err = 0;
#define match(a, b) (!strnicmp((a), (b), strlen(b)))
static OBJLIST *curr_objlist = NULL;
static char *boundstypes[] = { "NONE", "SPHERE", "BOX", "CSG", NULL };
void set_readseg_objlist(OBJLIST *olist)
{
curr_objlist = olist;
}
static SEGMENT **seg_array = NULL;
static int seg_array_size = 0;
void set_readseg_seglist(SEGMENT **ptr, int maxsegs)
{
seg_array = ptr;
seg_array_size = maxsegs;
}
static unsigned cmap[1000];
static int cmapsize = 0;
static process_attribute(char *buff, SEGMENT *seg)
{
char filename[100];
float sx = 1, sy = 1, sz = 1;
long tx = 0, ty = 0, tz = 0;
int depth = 0;
FILE *in;
cmapsize = 0;
while (isspace(*buff)) ++buff;
if (match(buff, "plgfile")) {
OBJECT *obj;
char mapfile[100];
mapfile[0] = '\0';
sscanf(buff, "plgfile = %s scale %f,%f,%f shift %ld,%ld,%ld sort %d map %s", filename, &sx, &sy, &sz, &tx, &ty, &tz, &depth, mapfile);
if (mapfile[0]) {
if ((in = fopen(mapfile, "r")) == NULL) {
readseg_err = -1;
return -1;
}
for (cmapsize = 0; cmapsize < sizeof(cmap)/sizeof(unsigned) && !feof(in); ++cmapsize) {
char buff[100], *p;
fgets(buff, sizeof(buff), in);
cmap[cmapsize] = (unsigned) strtoul(buff,&p,0); /* req so hex colors usable */
}
fclose(in);
}
set_loadplg_scale(sx, sy, sz);
set_loadplg_offset(tx, ty, tz);
set_loadplg_depthsort(depth);
set_loadplg_colormap(cmap, cmapsize);
seg_set_load_info(seg, filename, sx, sy, sz, tx, ty, tz);
if ((in = fopen(filename, "r")) == NULL) {
readseg_err = -1;
return -1;
}
if ((obj = load_plg(in)) == NULL) {
readseg_err = -2;
fclose(in);
return -2;
}
seg_setrep(seg, obj);
set_object_owner(obj, seg);
if (curr_objlist) add_to_objlist(curr_objlist, obj);
fclose(in);
return 0;
}
else if (match(buff, "pos")) {
long tx, ty, tz;
sscanf(buff, "pos = %ld,%ld,%ld", &tx, &ty, &tz);
abs_move_segment(seg, tx, ty, tz);
}
else if (match(buff, "rot")) {
float rx, ry, rz;
sscanf(buff, "rot = %f,%f,%f", &rx, &ry, &rz);
abs_rot_segment(seg, (long) (rx * 65536L), (long) (ry * 65536L), (long) (rz * 65536L));
}
else if (match(buff, "min")) {
long lims[12];
char *p;
if ((p = strchr(buff, '=')) == NULL) return 0;
do ++p; while (isspace(*p));
switch (tolower(buff[3])) {
case 'x':
lims[0] = atol(p);
set_seg_limits(seg, lims, LIM_MINTX);
break;
case 'y':
lims[2] = atol(p);
set_seg_limits(seg, lims, LIM_MINTY);
break;
case 'z':
lims[4] = atol(p);
set_seg_limits(seg, lims, LIM_MINTZ);
break;
case 'r':
switch (tolower(buff[4])) {
case 'x':
lims[6] = atof(p) * 65536L;
set_seg_limits(seg, lims, LIM_MINRX);
break;
case 'y':
lims[8] = atof(p) * 65536L;
set_seg_limits(seg, lims, LIM_MINRY);
break;
case 'z':
lims[10] = atof(p) * 65536L;
set_seg_limits(seg, lims, LIM_MINRZ);
break;
default: break;
}
default: break;
}
}
else if (match(buff, "max")) {
long lims[12];
char *p;
if ((p = strchr(buff, '=')) == NULL) return 0;
do ++p; while (isspace(*p));
switch (tolower(buff[3])) {
case 'x':
lims[1] = atol(p);
set_seg_limits(seg, lims, LIM_MAXTX);
break;
case 'y':
lims[3] = atol(p);
set_seg_limits(seg, lims, LIM_MAXTY);
break;
case 'z':
lims[5] = atol(p);
set_seg_limits(seg, lims, LIM_MAXTZ);
break;
case 'r':
switch (tolower(buff[4])) {
case 'x':
lims[7] = atof(p) * 65536L;
set_seg_limits(seg, lims, LIM_MAXRX);
break;
case 'y':
lims[9] = atof(p) * 65536L;
set_seg_limits(seg, lims, LIM_MAXRY);
break;
case 'z':
lims[11] = atof(p) * 65536L;
set_seg_limits(seg, lims, LIM_MAXRZ);
break;
default: break;
}
default: break;
}
}
else if (match(buff, "name")) {
char *p;
if ((p = strchr(buff, '=')) == NULL) {
readseg_err = -3;
return -3;
}
do ++p; while (isspace(*p));
seg_setname(seg, p);
}
#ifdef HAVEBOUNDS
else if (match(buff, "boundstype")) {
char *p;
int i;
if ((p = strchr(buff, '=')) == NULL) {
readseg_err = -3;
return -3;
}
do ++p; while (isspace(*p));
for (i = 0; boundstypes[i]; ++i)
if (match(p, boundstypes[i]))
break;
if (boundstypes[i] == NULL) i = 0;
set_seg_boundtype(seg, (unsigned char) i);
}
else if (match(buff, "boundsorig")) {
long x = 0, y = 0, z = 0;
sscanf(buff, "boundsorig = %ld,%ld,%ld", &x, &y, &z);
set_seg_boundorig(seg, x, y, z);
}
else if (match(buff, "boundslimits")) {
long x = 0, y = 0, z = 0;
sscanf(buff, "boundslimits = %ld,%ld,%ld", &x, &y, &z);
set_seg_boundlimits(seg, x, y, z);
}
else if (match(buff, "hotspot")) {
long x = 0, y = 0, z = 0;
sscanf(buff, "hotspot = %ld,%ld,%ld", &x, &y, &z);
add_hotspot(seg, x, y, z);
}
#endif
else if (match(buff, "segnum")) {
int j;
sscanf(buff, "segnum = %d", &j);
if (seg_array && j < seg_array_size) seg_array[j] = seg;
}
/* ignore anything we don't understand */
return 0;
}
SEGMENT *readseg(FILE *in, SEGMENT *parent)
{
SEGMENT *seg;
char buff[256];
int c, i = 0;
if ((seg = new_seg(parent)) == NULL) return NULL;
while ((c = getc(in)) != EOF) {
switch (c) {
case '{':
readseg(in, seg);
break;
case '}':
return seg;
case ';':
buff[i] = '\0';
process_attribute(buff, seg);
i = 0;
break;
default:
if (i < sizeof(buff)-1) buff[i++] = c;
break;
}
}
return seg;
}
static void indent(FILE *out, int level)
{
while (level--) fprintf(out, "\t");
}
writeseg(FILE *out, SEGMENT *s, int level)
{
SEGMENT *p;
void *q;
long tx, ty, tz, rx, ry, rz;
float frx, fry, frz;
char *name;
unsigned char btype;
unsigned w;
long lims[12];
int depth;
int i;
indent(out, level);
fprintf(out, "{\n");
if ((name = seg_getname(s)) != NULL) {
indent(out, level);
fprintf(out, "name = %s;\n", name);
}
seg_getposition(s, &tx, &ty, &tz, &rx, &ry, &rz);
indent(out, level);
fprintf(out, "pos = %ld,%ld,%ld;\n", tx, ty, tz);
indent(out, level);
fprintf(out, "rot = %f,%f,%f;\n", ((float) rx) / 65536L, ((float) ry) / 65536L, ((float) rz) / 65536L);
w = get_seg_limits(s, lims);
if (w & LIM_MINTX) { indent(out, level); fprintf(out, "minx = %ld;\n", lims[0]); }
if (w & LIM_MAXTX) { indent(out, level); fprintf(out, "maxx = %ld;\n", lims[1]); }
if (w & LIM_MINTY) { indent(out, level); fprintf(out, "miny = %ld;\n", lims[2]); }
if (w & LIM_MAXTY) { indent(out, level); fprintf(out, "maxy = %ld;\n", lims[3]); }
if (w & LIM_MINTZ) { indent(out, level); fprintf(out, "minz = %ld;\n", lims[4]); }
if (w & LIM_MAXTZ) { indent(out, level); fprintf(out, "maxz = %ld;\n", lims[5]); }
if (w & LIM_MINRX) { indent(out, level); fprintf(out, "minrx = %f;\n", ((float) lims[6])/65536.0); }
if (w & LIM_MAXRX) { indent(out, level); fprintf(out, "maxrx = %f;\n", ((float) lims[7])/65536.0); }
if (w & LIM_MINRY) { indent(out, level); fprintf(out, "minry = %f;\n", ((float) lims[8])/65536.0); }
if (w & LIM_MAXRY) { indent(out, level); fprintf(out, "maxry = %f;\n", ((float) lims[9])/65536.0); }
if (w & LIM_MINRZ) { indent(out, level); fprintf(out, "minrz = %f;\n", ((float) lims[10]/65536.0)); }
if (w & LIM_MAXRZ) { indent(out, level); fprintf(out, "maxrz = %f;\n", ((float) lims[11]/65536.0)); }
#ifdef HAVEBOUNDS
btype = get_seg_boundinfo(s, &tx, &ty, &tz, &rx, &ry, &rz);
if (btype) {
indent(out, level);
fprintf(out, "boundstype = %s;\n", boundstypes[btype]);
indent(out, level);
fprintf(out, "boundsorig = %ld,%ld,%ld;\n", tx, ty, tz);
indent(out, level);
fprintf(out, "boundslimits = %ld,%ld,%ld;\n", rx, ry, rz);
}
for (q = first_hotspot(s, &tx, &ty, &tz); q; q = next_hotspot(q, &tx, &ty, &tz)) {
indent(out, level);
fprintf(out, "hotspot = %ld,%ld,%ld;\n", tx, ty, tz);
}
#endif
name = seg_get_load_info(s, &frx, &fry, &frz, &tx, &ty, &tz);
indent(out, level);
if ((q = seg_getrep(s)) != NULL) depth = get_object_sorting(q);
else depth = 0;
fprintf(out, "plgfile = %s scale %f,%f,%f shift %ld,%ld,%ld sort %d;\n", name, frx, fry, frz, tx, ty, tz, depth);
for (p = child_segment(s); p; p = sibling_segment(p))
writeseg(out, p, level+1);
indent(out, level);
fprintf(out, "}\n");
return 0;
}